goog.require('dkpoints.nav.AuthHandler');
goog.require('dkpoints.tests.stubFn');


var stubFn = dkpoints.tests.stubFn,
    sp, handler, auth, authStatus, baseURL = 'http://localhost:8080';

function setUp() {
  auth = {};
  nav = {
    getReferer: function() { return ''; }
  };
  sp = {
    getBaseURL: function() { return baseURL; },
    getAuth: function() { return auth; },
    getNavManager: function() { return nav; }
  };
}


/**
 * Test that dependency references are stored correctly.
 */
var testConstructorParamsAreStoredCorrectly = function() {
  var handler = new dkpoints.nav.AuthHandler(sp);
  assertEquals('handler.baseURL should be what we gave it.',
               baseURL, handler.baseURL_);
  assertEquals('handler.auth_ should be what we gave it.',
               auth, handler.auth_);
  assertEquals('handler.navManager_ should be what we gave it.',
               nav, handler.navManager_);
};


/**
 * Test that logging in auth.login with the right arguments.
 */
var testHandleLogin = function() {
  var testReferer = '/standings';
  nav.getReferer = stubFn(testReferer);

  auth.login = stubFn();

  // Mock other potential code paths out of handle().
  auth.logout = stubFn();

  var realSetLocationHash = dkpoints.utils.setLocationHash;
  dkpoints.utils.setLocationHash = stubFn();

  handler = new dkpoints.nav.AuthHandler(sp);
  handler.handle({
    params: 'login'
  });

  assertTrue('auth.login should have been called.', auth.login.called);
  assertEquals('auth.login should\'ve been given the correct base url.',
               baseURL, auth.login.args[0]);
  assertEquals('auth.login should\'ve been passed the correct referer.',
               testReferer, auth.login.args[1]);

  // Verify other code paths weren't taken.
  assertFalse('auth.logout should not have been called.', auth.logout.called);
  assertFalse('setLocationHash should not have been called.',
              dkpoints.utils.setLocationHash.called);

  dkpoints.utils.setLocationHash = realSetLocationHash;
};


/**
 * Test that navigating to the logout url calls auth.logout (regardless of
 * whether or not the user is logged in).
 */
var testHandleLogout = function() {
  auth.login = stubFn();
  auth.logout = stubFn();

  var redirectHash = null,
      realSetHash = dkpoints.utils.setLocationHash;
  dkpoints.utils.setLocationHash = stubFn();

  var testReferer = '/raid/235';
  nav.getReferer = stubFn(testReferer);

  handler = new dkpoints.nav.AuthHandler(sp);
  handler.handle({
    params: 'logout'
  });

  var givenCallback = auth.logout.args[0];
  assertTrue('auth.logout should have been given a callback function',
             typeof givenCallback === 'function');
  assertEquals('handler should have stored the referer value for later use.',
               testReferer, handler.referer_);

  givenCallback();
  assertEquals('The callback given to auth.logout should have called ' +
               'setLocationHash with the referer passed to handle.',
               testReferer, dkpoints.utils.setLocationHash.args[0]);

  dkpoints.utils.setLocationHash = realSetHash;
};


/**
 * Test that calling AuthHandler.transition delegates to handle().
 */
var testTransitionDelegatesToHandle = function() {
  var path = {},
      realHandle = dkpoints.nav.AuthHandler.prototype.handle,
      handle = dkpoints.nav.AuthHandler.prototype.handle = stubFn();

  handler = new dkpoints.nav.AuthHandler(sp);
  handler.transition(path);

  assertTrue('Transition should have called handle().', handle.called);
  assertEquals('Handle should have been passed the path object.',
               path, handle.args[0]);

  dkpoints.nav.AuthHandler.prototype.handle = realHandle;
};


/**
 * Test that logoutComplete sets location.hash back to the referring page.
 */
var testLogoutCompleteReturnsToReferer = function() {
  var referer = '/admin/raid/235',
      realSetHash = dkpoints.utils.setLocationHash,
      mockSetHash = dkpoints.utils.setLocationHash = stubFn();

  auth.logout = stubFn();
  nav.getReferer = stubFn(referer);
  handler = new dkpoints.nav.AuthHandler(sp);
  handler.handle({
    path: 'logout'
  });

  handler.logoutComplete();

  assertEquals('setLocationHash should\'ve been called with the  referer.',
               referer, mockSetHash.args[0]);

  dkpoints.utils.setLocationHash = realSetHash;
};


/**
 * Test that exit clears the referer and calls its callback.
 */
var testExitDisposesAndCallsBack = function() {
  var callback = stubFn();

  handler = new dkpoints.nav.AuthHandler(sp);
  handler.referer_ = 'Hello.';

  handler.exit(callback);

  assertNull('Handler.referer_ should\'ve been set to null.', handler.referer_);
  assertTrue('postDisposeCallback should have been passed true.',
             callback.args[0]);
};

function tearDown() {
  handler = null;
}
